home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 July / macformat-026.iso / mac / Shareware City / Developers / NString 1.0 beta / Sources / NString_Concatenation.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-12  |  7.5 KB  |  226 lines  |  [TEXT/KAHL]

  1.  
  2. #include <string.h>
  3. #include <stdlib.h>
  4.  
  5. #include "NString.h"
  6. #include "NString_Misc.h"
  7.  
  8. //_________________________________________________________________________________
  9.  
  10. NString& NString::operator+= (const char *s)
  11. {
  12.     const char *fname = "operator+= (const char *)";
  13.     unsigned long int new_length;
  14.     
  15.     if ((s == NULL) || (s[0] == '\0'))                // empty string given to add
  16.         return (*this);
  17.     new_length = strlen(s) + sb->len;                // the new NString's length
  18.     if (sb->refs > 1)                                        // string body is used by someone else
  19.     {
  20.         strbody *old_sb = sb;
  21.     
  22.         if (! GetNewSB(new_length))
  23.             OUT_OF_MEM(fname);
  24.         strcpy(sb->str, old_sb->str);                    // copy the original part of the string
  25.         strcpy(sb->str + old_sb->len, s);            // copy the new part of the string
  26.     }
  27.     else                                                            // the string body may be modified freely
  28.     {
  29.         if (! ReallocStrBuf(new_length))                    // will NOT modify "sb->len"  :-)
  30.             OUT_OF_MEM(fname);
  31.         strcpy(sb->str + sb->len, s);                    // add the new part to the string
  32.         sb->len = new_length;
  33.     }
  34.     return (*this);
  35. }
  36.  
  37. //_________________________________________________________________________________
  38.  
  39. NString& NString::operator+= (const NString& s)
  40. {
  41.     const char *fname = "operator+= (const NString&)";
  42.     unsigned long int new_length;
  43.     
  44.     if (s.sb->len == 0)                                                                    // empty NString given to add
  45.         return (*this);
  46.     new_length = s.sb->len + sb->len;                                            // the new NString's length
  47.     if (sb->refs > 1)                                                                    // my string body is used by someone else
  48.     {
  49.         strbody *old_sb = sb;
  50.         unsigned long int old_s_len = s.sb->len;
  51.     
  52.         if (! GetNewSB(new_length))
  53.             OUT_OF_MEM(fname);
  54.         strcpy(sb->str, old_sb->str);                                                // copy the original part of the string
  55.         memmove(sb->str + old_sb->len, s.sb->str, old_s_len);        // copy the new part of the string
  56.             // memmove() MUST be used instead of strcpy() to protect against "s += s" !!!
  57.             // Moreover, "old_s_len" must be used as move-length, not "s.sb->len",
  58.             //         otherwise memmove() overwrites innocent memory in the case of "s += s" !
  59.     }
  60.     else                                                                                        // the string body may be modified freely
  61.     {
  62.         if (! ReallocStrBuf(new_length))                                            // will NOT modify "sb->len"
  63.             OUT_OF_MEM(fname);
  64.         memmove(sb->str + sb->len, s.sb->str, s.sb->len+1);            // add the new part to the string
  65.             // memmove() MUST be used instead of strcpy() to protect against "s += s" !!!
  66.         sb->len = new_length;
  67.             // new length must be inscribed AFTER the call to memmove() !
  68.     }
  69.     return (*this);
  70. }
  71.  
  72. //_________________________________________________________________________________
  73.  
  74. NString& NString::operator+= (const char c)
  75. {
  76.     const char *fname = "operator+= (const char)";    // the method's name (for error handling purposes)
  77.     unsigned long int new_length;
  78.     
  79.     if (c == '\0')                                                // tried to add NUL character
  80.         USAGE_ERR(fname, "Attempted to add NUL character to NString");
  81.     new_length = sb->len + 1;                            // the new NString's length
  82.     if (sb->refs > 1)                                        // string body is used by someone else
  83.     {
  84.         strbody *old_sb = sb;
  85.     
  86.         if (! GetNewSB(new_length))
  87.             OUT_OF_MEM(fname);
  88.         strcpy(sb->str, old_sb->str);                    // copy the original part of the string
  89.         sb->str[old_sb->len] = c;                        // add the character
  90.     }
  91.     else                                                            // the string body may be modified freely
  92.     {
  93.         if (! ReallocStrBuf(new_length))                // will NOT modify "sb->len" :-)
  94.             OUT_OF_MEM(fname);
  95.         sb->str[sb->len] = c;                                // add the character
  96.         sb->str[sb->len+1] = '\0';                        // terminate the new string
  97.         sb->len = new_length;
  98.     }
  99.     return (*this);
  100. }
  101.  
  102. //_________________________________________________________________________________
  103.  
  104. NString NString::operator+ (const char *s) const
  105. {
  106.     unsigned long int new_length = strlen(s) + sb->len;
  107.     NString result(new_length);                                    // create an uninitialized NString
  108.     
  109.     strcpy(result.sb->str, sb->str);                                // copy my own string part
  110.     strcpy(result.sb->str + sb->len, s);                        // copy the C-String part
  111.     return (result);
  112. }
  113.  
  114. //_________________________________________________________________________________
  115.  
  116. NString NString::operator+ (NString& s) const
  117. {
  118.     unsigned long int new_length = s.sb->len + sb->len;
  119.     NString result(new_length);                                    // create an uninitialized NString
  120.     
  121.     strcpy(result.sb->str, sb->str);                                // copy my own string part
  122.     strcpy(result.sb->str + sb->len, s.sb->str);            // copy the other NString's part
  123.     return (result);
  124. }
  125.  
  126. //_________________________________________________________________________________
  127.  
  128. NString NString::operator+ (const char c) const
  129. {
  130.     unsigned long int new_length = sb->len + 1;
  131.     NString result(new_length);                                    // create an uninitialized NString
  132.     
  133.     if (c == '\0')
  134.         USAGE_ERR("operator+ (const char)", "Attempted to add NUL character to NString");
  135.     strcpy(result.sb->str, sb->str);                                // copy my own string part
  136.     result.sb->str[sb->len] = c;                                    // copy the character
  137.     return (result);
  138. }
  139.  
  140. //_________________________________________________________________________________
  141.  
  142. NString operator+ (const char *s, const NString& ns)
  143. {
  144.     size_t s_length = strlen(s);
  145.     unsigned long int new_length = s_length + ns.sb->len;
  146.     NString result(new_length);                                        // create an uninitialized NString
  147.     
  148.     strcpy(result.sb->str, s);                                            // copy the C-String part
  149.     strcpy(result.sb->str + s_length, ns.sb->str);                // copy the NString part
  150.     return (result);
  151. }
  152.  
  153. //_________________________________________________________________________________
  154.  
  155. NString operator+ (const char c, const NString& ns)
  156. {
  157.     unsigned long int new_length = ns.sb->len + 1;
  158.     NString result(new_length);                                        // create an uninitialized NString
  159.     
  160.     if (c == '\0')
  161.     USAGE_ERR("operator+ (const char, const NString&)", "Attempted to add NUL character to NString");
  162.     result.sb->str[0] = c;                                                    // copy the character
  163.     strcpy(result.sb->str + 1, ns.sb->str);                        // copy the NString part
  164.     return (result);
  165. }
  166.  
  167. //_________________________________________________________________________________
  168.  
  169. NString& NString::operator*= (const unsigned long int k)
  170. {
  171.     const char *fname = "operator*= (const unsigned long int)";
  172.     unsigned long int new_length = k * sb->len;
  173.     unsigned long int i;
  174.     
  175.     if (new_length == sb->len)                                            // either k==1 or NString is empty
  176.         return (*this);
  177.     if (sb->refs > 1)
  178.     {
  179.         strbody *old_sb = sb;
  180.         
  181.         if (! GetNewSB(new_length))
  182.             OUT_OF_MEM(fname);
  183.         if (new_length != 0)
  184.             for (i=0; i < k; i++)                                            // copy my string k times
  185.                 strcpy(sb->str + i*old_sb->len, old_sb->str);
  186.     }
  187.     else
  188.     {
  189.         if (! ReallocStrBuf(new_length))                                // will NOT modify "sb->len"
  190.             OUT_OF_MEM(fname);
  191.         if (new_length == 0)
  192.             sb->str[0] = '\0';                                                // initialize empty string
  193.         else
  194.         {
  195.             for (i=1; i < k; i++)                                            // concatenate my string k-1 times
  196.                 memmove(sb->str + i*sb->len, sb->str, sb->len);
  197.                 // "memmove()" must be used instead of "strcpy()" or "memcpy()" as the terminator
  198.                 // of the source is overwritten by the copy
  199.             sb->str[new_length] = '\0';
  200.                 // must terminate the new string manually, as during the nth call to "memcpy()"
  201.                 // the NUL terminator of the source has already been overwritten.
  202.         }
  203.         sb->len = new_length;
  204.     }
  205.     return (*this);
  206. }
  207.  
  208. //_________________________________________________________________________________
  209.  
  210. NString NString::operator* (const unsigned long int k) const
  211. {
  212.     unsigned long int new_length = k * sb->len;
  213.     NString result(new_length);
  214.     unsigned long int i;
  215.     
  216.     if (new_length == sb->len)                                            // either k==1 or NString is empty
  217.         return (*this);
  218.     if (new_length == 0)
  219.         return (result);
  220.     
  221.     for (i=0; i < k; i++)
  222.         strcpy(result.sb->str + i*sb->len, sb->str);
  223.     return (result);
  224. }
  225.     
  226.